package com.molichuxing.gateway.bff.order.services.impl;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.dto.UploadFileRequestDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.BigDecimalUtils;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.DingTalkUtil;
import com.molichuxing.framework.utils.EmailUtil;
import com.molichuxing.gateway.bff.order.convertor.Convert;
import com.molichuxing.gateway.bff.order.services.FileStorageBffService;
import com.molichuxing.gateway.bff.order.services.OrderBffService;
import com.molichuxing.services.business.dto.request.create.ContractMileagePurchasedBizCreateDto;
import com.molichuxing.services.business.dto.request.create.ContractRenegeBizCreateDto;
import com.molichuxing.services.business.dto.request.create.ContractSubscribeBizCreateDto;
import com.molichuxing.services.business.dto.request.create.MessageCenterCreateBizDto;
import com.molichuxing.services.business.dto.request.modify.OrderPayModifyBizDto;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.*;
import com.molichuxing.services.contants.OrderConst;
import com.molichuxing.services.infrastructure.dto.request.create.InvoiceCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.MessageCenterCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.MessageContentCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.NotifyPushCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderPayModifyDto;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 订单bff
 *
 * @author zoumingyu
 * @date 2019年10月29日
 *
 */
@Service("orderBffService")
public class OrderBffServiceImpl implements OrderBffService {
	private static final Logger logger = LoggerFactory.getLogger(OrderBffServiceImpl.class);

	@Value("${profiles.active}")
	private String ACTIVE;

	@Value("${profiles.active.explain}")
	private String ACTIVE_EXPLAIN;

	@Value("${email_account}")
	private String EMAIL_ACCOUNT;

	@Value("${email_password}")
	private String EMAIL_PASSWORD;

	@Resource
	private OrderSubscribeService orderSubscribeService;

	@Resource
	private OrderExclusivelService orderExclusivelService;

	@Resource
	private OrderBizService orderBizService;

	@Resource
	private OrderExclusivelBizService orderExclusivelBizService;

	@Resource
	private OrderSubscribeBizService orderSubscribeBizService;

	@Resource
	private OrderScheduleService orderScheduleService;

	@Resource
	private OrderMileageService orderMileageService;

	@Resource
	private OrderPurchaseBizService orderPurchaseBizService;

	@Resource
	private OrderDelayBizService orderDelayBizService;

	@Resource
	private OrderSubscribeSettlementService orderSubscribeSettlementService;

	@Resource
	private OrderRenegeBizService orderRenegeBizService;

	@Resource
	private UserService userService;

	@Resource
	private UserDetailService userDetailService;

	@Resource
	private InvoiceService invoiceService;

	@Resource
	private DealerDetailService dealerDetailService;

	@Resource
	private StoreService storeService;

	@Resource
	private DealerService dealerService;

	@Resource
	private SubcompanyService subcompanyService;

	@Resource
	private UserBizService userBizService;

	@Resource
	private RegionService regionService;

	@Resource
	private CarService carService;

	@Resource
	private CarBizService carBizService;

	@Resource
	private VehicleBizService vehicleBizService;

	@Resource
	private VehicleColorService vehicleColorService;

	@Resource
	private FileStorageBffService fileStorageBffService;

	@Resource
	private ContractBizService contractBizService;

	@Resource
	private ContractService contractService;

	@Resource
	private SmsBizService smsBizService;

	@Resource
	private MessageCenterBizService messageCenterBizService;

	@Resource
	private MessageCenterService messageCenterService;

	@Resource
	private MessageTemplateService messageTemplateService;

	@Resource
	private NotifyPushService notifyPushService;

	@Resource
	private RiskEmailService riskEmailService;

	@Resource
	private BlacklistService blacklistService;

	@Resource
	private IovCarService iovCarService;

	@Resource
	private OrderRenegeService orderRenegeService;

	/**
	 * 支付完成修改订单信息
	 *
	 * @param notifyBizDto
	 */
	@Async
	@Override
	public void modifyOrderPay(NotifyBizDto notifyBizDto) {
		logger.info("[modifyOrderPay]支付完成修改订单信息:" + JSONObject.toJSONString(notifyBizDto));
		try {
			boolean result = false;
			// 查询用户信息
			UserDto userDto = userService.getUser(notifyBizDto.getUserId());
			// 判断业务类型
			if (PaymentBusinessTypeEnum.EXCLUSIVEL.equals(notifyBizDto.getBusinessType())) {
				// 专属订单
				result = this.modifyExclusivelOrderPay(notifyBizDto, userDto);
			} else if (PaymentBusinessTypeEnum.SUBSCRIBE.equals(notifyBizDto.getBusinessType())) {
				// 订阅订单
				result = this.modifySubscribeOrderPay(notifyBizDto, userDto);
			}
			if (result) {
				// 修改成功，进行其他操作
				otherOperation(notifyBizDto, userDto);
			} else {
				String str = JSONObject.toJSONString(notifyBizDto);
				logger.error("支付回调修改订单信息失败：{}", str);
				String strTmp = ACTIVE_EXPLAIN + "支付回调修改订单信息失败：" + str;
				DingTalkUtil.exceptionSend(strTmp);
			}
		} catch (Exception e) {
			logger.error("[modifyOrderPay]支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成修改订单信息异常：", e);
			DingTalkUtil.exceptionSend(
					ACTIVE_EXPLAIN + "支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成修改订单信息异常：" + e.getMessage());
		}
	}

	/**
	 * 支付完成修改订阅订单信息
	 * 
	 * @param userDto
	 * 
	 * @param notifyBizDto
	 */
	private Boolean modifySubscribeOrderPay(NotifyBizDto notifyBizDto, UserDto userDto) {
		Boolean result = false;
		// 判断费用类型
		if (PaymentCostTypeEnum.SUBSCRIBE.equals(notifyBizDto.getCostType())) {
			// 订购
			OrderPayModifyBizDto modifyDto = Convert.toOrderPayModifyBizDto(notifyBizDto, userDto);
			result = orderSubscribeBizService.modifyPaySuccess(modifyDto);
		} else if (PaymentCostTypeEnum.RENEW.equals(notifyBizDto.getCostType())) {
			// 续订
			OrderPayModifyBizDto modifyDto = Convert.toOrderPayModifyBizDto(notifyBizDto, userDto);
			result = orderSubscribeBizService.modifyPaySuccess(modifyDto);
		} else if (PaymentCostTypeEnum.PURCHASE.equals(notifyBizDto.getCostType())) {
			// 加购
			OrderPayModifyBizDto modifyDto = Convert.toOrderPayModifyBizDto(notifyBizDto, userDto);
			result = orderPurchaseBizService.modifyPaySuccess(modifyDto);
		} else if (PaymentCostTypeEnum.SETTLEMENT.equals(notifyBizDto.getCostType())) {
			// 结算
			OrderPayModifyBizDto modifyDto = Convert.toOrderPayModifyBizDto(notifyBizDto, userDto);
			result = orderSubscribeBizService.modifySettlement(modifyDto);
		}

		return result;
	}

	/**
	 * 支付完成修改专属订单信息
	 *
	 * @param notifyBizDto
	 * @param userDto
	 */
	private Boolean modifyExclusivelOrderPay(NotifyBizDto notifyBizDto, UserDto userDto) {
		Boolean result = false;
		// 判断费用类型
		if (PaymentCostTypeEnum.SUBSCRIBE.equals(notifyBizDto.getCostType())) {
			// 订购（首付）
			OrderPayModifyBizDto modifyDto = Convert.toOrderPayModifyBizDto(notifyBizDto, userDto);
			result = orderExclusivelBizService.modifyPaySuccess(modifyDto);
		} else if (PaymentCostTypeEnum.REPAYMENT.equals(notifyBizDto.getCostType())) {
			// 还款
			OrderPayModifyDto modifyDto = Convert.toOrderPayModifyDto(notifyBizDto, userDto);
			result = orderScheduleService.modifyPay(modifyDto);
		} else if (PaymentCostTypeEnum.RENEGE.equals(notifyBizDto.getCostType())) {
			// 退租缴费
			OrderPayModifyBizDto modifyDto = Convert.toOrderPayModifyBizDto(notifyBizDto, userDto);
			result = orderRenegeBizService.modifyPay(modifyDto);
		}

		return result;
	}

	private void otherOperation(NotifyBizDto notifyBizDto, UserDto userDto) {
		if (PaymentCostTypeEnum.SUBSCRIBE.equals(notifyBizDto.getCostType())) {
			// 订购
			// 将用户置为已支付
			modifyUserPay(userDto);
			// 去除延时任务
			deleteDelay(notifyBizDto.getOrderCode());
			// 发送短信、推送等
			pushMsgSubscribe(notifyBizDto, userDto);
			// 创建发票
			createSubscribeInvoice(notifyBizDto);
		} else if (PaymentCostTypeEnum.REPAYMENT.equals(notifyBizDto.getCostType())) {
			// 还款,查询排期信息
			List<OrderScheduleDto> orderScheduleDtos = orderScheduleService
					.getOrderSchedule(notifyBizDto.getOrderCode());
			// 还款完成，判断是否需要修改删除黑名单，需要则修改删除
			blackList(orderScheduleDtos, notifyBizDto.getOrderCode(), userDto);
			// 车辆解锁
			carDecontrol(orderScheduleDtos, notifyBizDto.getOrderCode(), userDto);
			// 发送短信、推送等
			pushMsgRepayment(notifyBizDto, userDto);
			// 创建发票
			createRepaymentInvoice(notifyBizDto);
		} else if (PaymentCostTypeEnum.RENEW.equals(notifyBizDto.getCostType())) {
			// 续订
			// 去除延时任务
			deleteDelay(notifyBizDto.getOrderCode());
			// 发送短信、推送等
			pushMsgRenew(notifyBizDto, userDto);
			// 创建发票
			createRenewInvoice(notifyBizDto);
			//生成合同
			createContract(notifyBizDto, ContractCreateEnum.RENEW);
		} else if (PaymentCostTypeEnum.PURCHASE.equals(notifyBizDto.getCostType())) {
			// 加购
			// 去除延时任务
			deleteDelay(notifyBizDto.getOrderCode());
			// 发送短信、推送等
			pushMsgPurchase(notifyBizDto, userDto);
			// 创建发票
			createPurchaseInvoice(notifyBizDto);
			//生成合同
			createContract(notifyBizDto, ContractCreateEnum.PURCHASE);
		} else if (PaymentCostTypeEnum.SETTLEMENT.equals(notifyBizDto.getCostType())) {
			// 结算
			// 发送短信、推送等
			pushMsgSettlement(notifyBizDto, userDto);
			// 创建发票
			createSettlementInvoice(notifyBizDto);
		} else if (PaymentCostTypeEnum.RENEGE.equals(notifyBizDto.getCostType())) {
			// 退租缴费
			// 发送短信、推送等
			pushMsgRenege(notifyBizDto, userDto);
			// 修改合同-协商失效
			contractService.modifyStatusByOrderCode(notifyBizDto.getOrderCode(),
					ContractStatusEnum.NEGOTIATE_NONEFFECTIVE.getValue());
			// 生成解除协议
			createContractRenege(notifyBizDto);
		}
	}

	private void createContractRenege(NotifyBizDto notifyBizDto) {
		// 需要发送邮件人员的邮箱信息
		List<String> emails = null;
		try {
			ContractRenegeBizCreateDto createDto = new ContractRenegeBizCreateDto();
			Integer storeId = null;
			// 查询订单信息
			OrderExclusivelBizDto orderExclusivel = (OrderExclusivelBizDto) orderBizService.getOrder(notifyBizDto.getOrderCode());
			if (orderExclusivel == null) {
				logger.error("[createContractRenege]订单({})不存在", notifyBizDto.getOrderCode());
				throw new BizException("用户订单异常");
			} else if (!orderExclusivel.getUserId().equals(notifyBizDto.getUserId())) {
				logger.error("[createContractRenege]订单用户({})和查询用户({})不一致", orderExclusivel.getUserId(), notifyBizDto.getUserId());
				throw new BizException("用户订单异常");
			} else if (orderExclusivel.getCarId() == null || orderExclusivel.getCarId() <= 0) {
				return;
			}
			storeId = orderExclusivel.getPlaceStoreId();
			orderExclusivel = null;

			// 查询退租信息
			OrderRenegeDto orderRenege = orderRenegeService.getEffectiveRenege(notifyBizDto.getOrderCode());
			if (orderRenege == null) {
				logger.error("[createContractRenege]订单({})不存在退租", notifyBizDto.getOrderCode());
				throw new BizException("用户订单异常");
			}
			createDto = Convert.toContractRenegeBizCreateDto(createDto, orderRenege);

			// 查询用户信息
			UserBizDto user = userBizService.getUser(notifyBizDto.getUserId());
			if (user == null) {
				logger.error("[createContractRenege]用户({})不存在", notifyBizDto.getUserId());
				throw new BizException("用户订单异常");
			}
			createDto = Convert.toContractRenegeBizCreateDto(createDto, user);

			//通过下单门店id查询经销商id
			StoreDto storeDto = storeService.getStoreById(storeId);
			if (null == storeDto || null == storeDto.getDealerId()) {
				logger.error("[createContractRenege]门店({})信息为空", storeId);
				throw new BizException("用户订单异常");
			}
			//通过经销商id查询分子公司id
			DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
			if (null == dealerDetailDto || null == dealerDetailDto.getSubcompanyId()) {
				logger.error("[createContractRenege]经销商({})详细信息为空", storeDto.getDealerId());
				throw new BizException("用户订单异常");
			}
			//通过分子公司id查询分子公司信息
			SubcompanyDto subcompanyDto = subcompanyService.getSubcompanyNameById(dealerDetailDto.getSubcompanyId());
			if (null == subcompanyDto) {
				logger.error("[createContractRenege]分子公司({})信息为空", dealerDetailDto.getSubcompanyId());
				throw new BizException("用户订单异常");
			}
			createDto = Convert.toContractRenegeBizCreateDto(createDto, subcompanyDto);
			// 签订时间
			createDto.setSignedTime(LocalDateTime.now());
			createDto.setSignedTime(LocalDateTime.now());
			createDto.setOrderCode(notifyBizDto.getOrderCode());

			// 文件上传信息
			UploadFileRequestDto uploadFileRequestDto = fileStorageBffService.getFileStorageConfig("contract");
			if (uploadFileRequestDto == null) {
				throw new Exception("文件存储配置查询失败");
			}

			// 生成解除协议
			if (!contractBizService.createRenege(createDto, uploadFileRequestDto)) {
				logger.error("[createContractRenege]订单(" + notifyBizDto.getOrderCode()
						+ ")生成解除协议失败，接口返回false");
				throw new BizException("生成解除协议失败，接口返回false");
			}

			// 解除协议修改为已终止
			try {
				contractService.modifyStatus(createDto.getOrderCode(), ContractStatusEnum.TERMINATED, Arrays.asList(ContractTypeEnum.RESCISSION_CONTRACT));
			} catch (Exception e) {
				logger.error("解除协议状态修改为已终止异常", e);
			}

		} catch (Exception e) {
			String msg = "订单(" + notifyBizDto.getOrderCode() + ")退租支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成生成解除协议失败：";
			logger.error(msg, e);
			//邮件
			emails = getEmail(RiskEmailTypeEnum.CONTRACT_GENERATION_FAILED); // getRiskEmailList(RiskEmailEnum.ONE.getValue());
			if (null != emails) {
				EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD, "生成解除协议失败", "亲，订单号" + notifyBizDto.getOrderCode() + "退租解除协议生成失败，请介入进一步处理。", emails);
			} else {
				logger.error("生成合同 未配置发送邮件人员的邮箱信息");
			}

			//钉钉
			DingTalkUtil.exceptionSend("亲，订单号" + notifyBizDto.getOrderCode() + "生成解除协议失败，请介入进一步处理。");

		}
	}

	/**
	 * 车辆解锁
	 *
	 * @param orderScheduleDtos
	 * @param orderCode
	 * @param userDto
	 */
	private void carDecontrol(List<OrderScheduleDto> orderScheduleDtos, Long orderCode, UserDto userDto) {
		try {
			for (OrderScheduleDto orderScheduleDto : orderScheduleDtos) {
				if (OrderScheduleStatusEnum.NO.equals(orderScheduleDto.getStatus())) {
					// 未还款，判断当前是否逾期
					long overdueDay = DateUtil.getDaysDiff(orderScheduleDto.getPayableDate(), LocalDateTime.now());
					if (overdueDay > 0L) {
						// 还存在逾期未还
						logger.info("订单(" + orderCode + ")排期(" + orderScheduleDto.getPeriods() + ")逾期未还");
						return;
					} else {
						break;
					}
				}
			}

			// 查询订单信息
			OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(orderCode);
			// 查询车辆信息
			CarDto carDto = carService.getCarById(orderExclusivel.getCarId());

			// 解除锁定车辆
			Boolean decontrolResult = iovCarService.modifyCarDecontrol(carDto.getVin(), "还款完成解锁车辆");
			int smsTemplate = 0;
			if (decontrolResult == null) {
				// 不需要解锁
				return;
			} else if (decontrolResult) {
				// 解锁成功
				smsTemplate = SmsTemplateEnum.CAR_DECONTROL_SUCCESS.getValue();
			} else {
				// 解锁失败
				smsTemplate = SmsTemplateEnum.CAR_DECONTROL_FAIL.getValue();
			}
			JSONObject json = new JSONObject();
			json.put("plate", carDto.getLicencePlate());
			// 发送短信
			smsBizService.sendMessage(userDto.getPhone(), smsTemplate, json.toJSONString(), null);
		} catch (Exception e) {
			logger.error("订单(" + orderCode + ")还款车辆解锁异常", e);
		}
	}

	/**
	 * 操作黑名单
	 *
	 * @param orderScheduleDtos
	 * @param orderCode
	 * @param userDto
	 */
	private void blackList(List<OrderScheduleDto> orderScheduleDtos, Long orderCode, UserDto userDto) {
		try {
			if (orderScheduleDtos == null || orderScheduleDtos.isEmpty()) {
				return;
			}
			int overdueNum = 0;
			boolean isWipe = true;
			for (OrderScheduleDto orderScheduleDto : orderScheduleDtos) {
				if (OrderScheduleStatusEnum.NO.equals(orderScheduleDto.getStatus())) {
					// 未还款，判断当前是否逾期
					long overdueDay = DateUtil.getDaysDiff(orderScheduleDto.getPayableDate(), LocalDateTime.now());
					if (overdueDay > 0L) {
						// 还存在逾期未还
						isWipe = false;
						break;
					}
				} else if (OrderScheduleStatusEnum.ALREADY.equals(orderScheduleDto.getStatus())) {
					long overdueDay = DateUtil.getDaysDiff(orderScheduleDto.getPayableDate(),
							orderScheduleDto.getPaySuccessTime());
					if (overdueDay > 0L) {
						overdueNum += 1;
					}
				}
			}
			if (overdueNum < OrderConst.OVERDUE_ACCUMULATED && isWipe) {
				// 移除黑名单（线下还款咋整??）
				UserBizDto userBizDto = userBizService.getUser(userDto.getId());
				if (blacklistService.modifyBlacklist(userBizDto.getIdNumber())) {
					userService.modifyIsBlack(userDto.getId(), false);
				}
			}

		} catch (Exception e) {
			logger.error("订单(" + orderCode + ")还款移除黑名单失败", e);
		}
	}

	private void pushMsgRenege(NotifyBizDto notifyBizDto, UserDto userDto) {
		// 保存消息
		String message = "您的订单“" + notifyBizDto.getOrderCode() + "”缴费成功！祝您生活愉快！";
		MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
		messageCenterCreateDto.setUserId(userDto.getId());
		messageCenterCreateDto.setTitle("缴费成功通知");
		messageCenterCreateDto.setMessage(message);
		messageCenterCreateDto.setType(MessageCenterTypeEnum.RENEW_CONFIRMATION_RESULTS_NOTICE.getValue());
		messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());

		messageCenterService.createMessageCenter(messageCenterCreateDto);
	}

	/**
	 * 结算新增站内信
	 * 
	 * @param notifyBizDto
	 * @param userDto
	 */
	private void pushMsgSettlement(NotifyBizDto notifyBizDto, UserDto userDto) {

		// 保存消息
		String message = "您的订单“" + notifyBizDto.getOrderCode() + "”缴费成功！祝您生活愉快！";
		MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
		messageCenterCreateDto.setUserId(userDto.getId());
		messageCenterCreateDto.setTitle("缴费成功通知");
		messageCenterCreateDto.setMessage(message);
		messageCenterCreateDto.setType(MessageCenterTypeEnum.RENEW_CONFIRMATION_RESULTS_NOTICE.getValue());
		messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());

		messageCenterService.createMessageCenter(messageCenterCreateDto);
	}

	/**
	 * 加购发送短信、推送等
	 * 
	 * @param notifyBizDto
	 * @param userDto
	 */
	private void pushMsgPurchase(NotifyBizDto notifyBizDto, UserDto userDto) {
		try {
			OrderMileageDto orderMileage = orderMileageService.getOrderMileage(notifyBizDto.getOrderCode());
			// 查询主订单信息
			OrderSubscribeDto orderSubscribe = orderSubscribeService
					.getOrderSubscribe(orderMileage.getMasterOrderCode());
			BigDecimal payAmount = orderMileage.getPurchaseFee().add(orderMileage.getBeyondFee());

			JSONObject json = new JSONObject();
			// 订单号
			json.put("order", orderMileage.getMasterOrderCode());
			// 支付金额
			json.put("amount", BigDecimalUtils.toString(payAmount));
			// 失效时间
			json.put("date", DateUtil.formatDate(orderSubscribe.getLeaseExpire(), "yyyy年MM月dd日"));
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ORDER_PAY_SMS_FIVE.getValue(),
						json.toJSONString(), null);
			} catch (Exception e) {
				logger.error(
						"加购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成发送短信异常",
						e);
			}
			// 发送推送
			try {
				// 推送数据
				MessageTemplateDto messageTemplateDto = messageTemplateService.getByKey("push_purchased_pay_success");
				String body = messageTemplateDto.getBody();
				body = body.replace("${orderCode}", orderMileage.getMasterOrderCode() + "")
						.replace("${cost}", BigDecimalUtils.toString(payAmount))
						.replace("${date}", DateUtil.formatDate(orderSubscribe.getLeaseExpire(), "yyyy年MM月dd日"));
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error(
						"加购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成发送推送异常",
						e);
			}

			// 保存消息
			String message = "您的订单“" + orderMileage.getMasterOrderCode()
					+ "”加购里程成功，本次加购里程费用（金额" + BigDecimalUtils.toString(payAmount)
					+ "元）已完成支付，该里程包将于" + DateUtil.formatDate(orderSubscribe.getLeaseExpire(), "yyyy年MM月dd日")
					+ "失效。合同请查看订单详情。客服热线400-0311-555。";
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("加购成功通知");
			messageCenterCreateDto.setMessage(message);
			messageCenterCreateDto.setType(MessageCenterTypeEnum.PURCHASE_CONFIRMATION_RESULTS_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());

			messageCenterService.createMessageCenter(messageCenterCreateDto);
		} catch (Exception e) {
			String msg = "加购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成发送消息异常：";
			logger.error(msg, e);
		}
	}

	/**
	 * 续订发送短信、推送等
	 * 
	 * @param notifyBizDto
	 * @param userDto
	 */
	private void pushMsgRenew(NotifyBizDto notifyBizDto, UserDto userDto) {
		try {
			OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(notifyBizDto.getOrderCode());
			BigDecimal payAmount = orderSubscribe.getCartFee().add(orderSubscribe.getDeposit());
			// 查询车型信息
			VehicleNameBizDto vehicleName = vehicleBizService.getCarByModel(orderSubscribe.getVehicleId());

			JSONObject json = new JSONObject();
			// 商品名称
			String product = vehicleName.getSubBrandName() + " " + vehicleName.getSeriesName() + " "
					+ vehicleName.getModelName() + " " + orderSubscribe.getTransportTime() + "个月/"
					+ orderSubscribe.getBaseMileage() + "公里, " + orderSubscribe.getPackageMileage() + "公里";
			json.put("product", product);
			// 支付金额
			json.put("amount", BigDecimalUtils.toString(payAmount));
			// 生效时间
			json.put("date", DateUtil.formatDate(orderSubscribe.getLeaseInception(), "yyyy年MM月dd日"));
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ORDER_PAY_SMS_FOUE.getValue(),
						json.toJSONString(), null);
			} catch (Exception e) {
				logger.error("续订(" + notifyBizDto.getOrderCode() + ")支付(支付流水号："
						+ notifyBizDto.getPayNumber() + ")完成发送短信异常", e);
			}
			// 发送推送
			try {
				// 推送数据
				MessageTemplateDto messageTemplateDto = messageTemplateService.getByKey("push_renew_pay_success");
				String body = messageTemplateDto.getBody();
				body = body.replace("${goodsName}", product).replace("${cost}", BigDecimalUtils.toString(payAmount))
						.replace("${date}", DateUtil.formatDate(orderSubscribe.getLeaseInception(), "yyyy年MM月dd日"));
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error("续订(" + notifyBizDto.getOrderCode() + ")支付(支付流水号："
						+ notifyBizDto.getPayNumber() + ")完成发送推送异常", e);
			}
			// 保存消息
			String message = "您已成功续订“" + product + "”，现已成功支付套餐费用（金额" + BigDecimalUtils.toString(payAmount)
					+ "元），续订订单将于" + DateUtil.formatDate(orderSubscribe.getLeaseInception(), "yyyy年MM月dd日")
					+ " 00:00：00起生效。客服热线400-0311-555。";
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("续订成功通知");
			messageCenterCreateDto.setMessage(message);
			messageCenterCreateDto.setType(MessageCenterTypeEnum.RENEWALS_RESULTS_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());

			messageCenterService.createMessageCenter(messageCenterCreateDto);

		} catch (Exception e) {
			String msg = "续订(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成发送消息异常：";
			logger.error(msg, e);
		}
	}

	/**
	 * 还款发送短信、推送等
	 * 
	 * @param notifyBizDto
	 * @param userDto
	 */
	private void pushMsgRepayment(NotifyBizDto notifyBizDto, UserDto userDto) {
		try {
			// 查询订单信息
			OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(notifyBizDto.getOrderCode());
			// 查询排期信息
			OrderScheduleDto orderScheduleDto = orderScheduleService.getOrderSchedule(notifyBizDto.getScheduleId());
			// 查询车型信息
			VehicleNameBizDto vehicleName = vehicleBizService.getCarByModel(orderExclusivel.getVehicleId());

			JSONObject json = new JSONObject();
			// 商品名称
			String paymentMethodStr = OrderPaymentMethodEnum.INSTALLMENT.equals(orderExclusivel.getPaymentMethod())
					? "月付" : orderExclusivel.getPaymentMethod().getName();
			String product = vehicleName.getSubBrandName() + " " + vehicleName.getSeriesName() + " "
					+ vehicleName.getModelName() + " " + orderExclusivel.getTransportTime() + "期/"
					+ (orderExclusivel.getIsBuyback() ? "回购/" : "不回购/") + paymentMethodStr;
			json.put("product", product);
			// 期数
			json.put("phase", orderScheduleDto.getPeriods());
			// 支付金额
			json.put("fee", BigDecimalUtils.toString(orderScheduleDto.getPayable()));
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ORDER_PAY_SMS_SIX.getValue(),
						json.toJSONString(), null);
			} catch (Exception e) {
				logger.error(
						"还款(" + notifyBizDto.getOrderCode() + ":" + notifyBizDto.getScheduleId() + ")支付(支付流水号："
								+ notifyBizDto.getPayNumber() + ")完成发送短信异常",
						e);
			}
			// 发送推送
			try {
				MessageTemplateDto messageTemplateDto = messageTemplateService.getByKey("push_repayment_success");
				String body = messageTemplateDto.getBody();
				body = body.replace("${goodsName}", product).replace("${periods}", orderScheduleDto.getPeriods() + "");
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(),
						messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error(
						"还款(" + notifyBizDto.getOrderCode() + ":" + notifyBizDto.getScheduleId() + ")支付(支付流水号："
								+ notifyBizDto.getPayNumber() + ")完成发送推送异常",
						e);
			}
			// 保存消息
			MessageCenterCreateBizDto messageCenterCreateBizDto = new MessageCenterCreateBizDto();
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("还款成功通知");
			messageCenterCreateDto.setMessage("您已还清本期用车费");
			messageCenterCreateDto.setType(MessageCenterTypeEnum.SUCCESSFUL_REPAYMENT_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
			List<MessageContentCreateDto> messageContentCreateDtos = new ArrayList<>();
			messageContentCreateDtos.add(new MessageContentCreateDto("还款时间",
					DateUtil.formatDate(notifyBizDto.getPayTime(), "yyyy年MM月dd日 HH:mm:ss"), 1));
			messageContentCreateDtos
					.add(new MessageContentCreateDto("还款金额",
							"¥" + BigDecimalUtils.toString(orderScheduleDto.getPayable()), 2));
			messageContentCreateDtos
					.add(new MessageContentCreateDto("还款期数", "第" + orderScheduleDto.getPeriods() + "期", 3));
			messageContentCreateDtos.add(new MessageContentCreateDto("还款项目", product, 4));

			messageCenterCreateBizDto.setMessageCenterCreateDto(messageCenterCreateDto);
			messageCenterCreateBizDto.setMessageContentCreateDtoList(messageContentCreateDtos);
			messageCenterBizService.careteMessageCenterBiz(messageCenterCreateBizDto);

		} catch (Exception e) {
			String msg = "还款(" + notifyBizDto.getOrderCode() + ":" + notifyBizDto.getScheduleId() + ")支付(支付流水号："
					+ notifyBizDto.getPayNumber() + ")完成发送消息异常：";
			logger.error(msg, e);
		}
	}

	/**
	 * 订购发送短信、推送等
	 * 
	 * @param notifyBizDto
	 * @param userDto
	 */
	private void pushMsgSubscribe(NotifyBizDto notifyBizDto, UserDto userDto) {
		try {
			JSONObject json = new JSONObject();
			Integer smsCode = null;
			VehicleNameBizDto vehicleName = null;
			StoreDto store = null;
			String product = null;
			NotifyPushCreateDto notifyPush = null;
			BigDecimal payAmount = null;
			boolean isAudit = false;
			String tmp = null;
			// 判断业务类型
			if (PaymentBusinessTypeEnum.EXCLUSIVEL.equals(notifyBizDto.getBusinessType())) {
				// 专属订单
				OrderExclusivelDto orderExclusivel = orderExclusivelService
						.getOrderExclusivel(notifyBizDto.getOrderCode());
				// 查询车型信息
				vehicleName = vehicleBizService.getCarByModel(orderExclusivel.getVehicleId());
				// 查询门店
				store = storeService.getStoreById(orderExclusivel.getPlaceStoreId());
				if (OrderPaymentMethodEnum.INSTALLMENT.equals(orderExclusivel.getPaymentMethod())) {
					// 月付
					smsCode = SmsTemplateEnum.ORDER_PAY_SMS_ONE.getValue();
					payAmount = orderExclusivel.getRental().add(orderExclusivel.getDeposit());
					isAudit = true;
					tmp="专属里程";
				} else if (OrderPaymentMethodEnum.FULL.equals(orderExclusivel.getPaymentMethod())) {
					// 全款
					smsCode = SmsTemplateEnum.ORDER_PAY_SMS_TWO.getValue();
					payAmount = orderExclusivel.getRental().add(orderExclusivel.getDeposit());
				}
				// 商品名称
				String paymentMethodStr = OrderPaymentMethodEnum.INSTALLMENT.equals(orderExclusivel.getPaymentMethod())
						? "月付" : orderExclusivel.getPaymentMethod().getName();
				product = vehicleName.getSubBrandName() + " " + vehicleName.getSeriesName() + " "
						+ vehicleName.getModelName() + " " + orderExclusivel.getTransportTime() + "期/"
						+ (orderExclusivel.getIsBuyback() ? "回购/" : "不回购/") + paymentMethodStr;
				json.put("product", product);
				// 支付金额
				json.put("amount", BigDecimalUtils.toString(payAmount));
				// 门店
				json.put("store", store.getFullName());
				// 日期
				json.put("num", 15);

				// 推送数据
				MessageTemplateDto messageTemplateDto = messageTemplateService.getByKey("push_pay_success");
				String body = messageTemplateDto.getBody();
				body = body.replace("${goodsName}", product);
				notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()), messageTemplateDto.getSubject(),
						messageTemplateDto.getSubject(), body, body, null, "");

			} else if (PaymentBusinessTypeEnum.SUBSCRIBE.equals(notifyBizDto.getBusinessType())) {
				// 订阅订单
				OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(notifyBizDto.getOrderCode());
				isAudit = true;
				tmp="订阅里程";
				payAmount = orderSubscribe.getCartFee().add(orderSubscribe.getDeposit());
				smsCode = SmsTemplateEnum.ORDER_PAY_SMS_THREE.getValue();
				// 查询车型信息
				vehicleName = vehicleBizService.getCarByModel(orderSubscribe.getVehicleId());
				// 查询门店
				store = storeService.getStoreById(orderSubscribe.getPlaceStoreId());
				// 商品名称
				product = vehicleName.getSubBrandName() + " " + vehicleName.getSeriesName() + " "
						+ vehicleName.getModelName() + " " + orderSubscribe.getTransportTime() + "个月/"
						+ orderSubscribe.getBaseMileage() + "公里, " + orderSubscribe.getPackageMileage() + "公里";
				json.put("product", product);
				// 支付金额
				json.put("amount", BigDecimalUtils.toString(payAmount));
				// 时间
				json.put("date", DateUtil.formatDate(LocalDate.now(), "yyyy年MM月dd日"));
				// 门店
				json.put("store", store.getFullName());

				// 推送数据
				MessageTemplateDto messageTemplateDto = messageTemplateService.getByKey("push_pay_success_two");
				String body = messageTemplateDto.getBody();
				body = body.replace("${goodsName}", product).replace("${cost}",
						BigDecimalUtils.toString(payAmount))
						.replace("${date}", DateUtil.formatDate(LocalDate.now(), "yyyy年MM月dd日"))
						.replace("${store}", store.getFullName());
				notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()), messageTemplateDto.getSubject(),
						messageTemplateDto.getSubject(), body, body, null, "");
			}
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), smsCode, json.toJSONString(), null);
			} catch (Exception e) {
				logger.error(
						"订购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成发送短信异常：",
						e);
			}
			// 发送推送
			try {
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error(
						"订购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber() + ")完成发送推送异常：",
						e);
			}
			// 保存消息
			MessageCenterCreateBizDto messageCenterCreateBizDto = new MessageCenterCreateBizDto();
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("支付成功通知");
			messageCenterCreateDto.setMessage("您成功支付了一笔款项");
			messageCenterCreateDto.setType(MessageCenterTypeEnum.SUCCESSFUL_PAYMENT_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
			List<MessageContentCreateDto> messageContentCreateDtos = new ArrayList<>();
			messageContentCreateDtos.add(new MessageContentCreateDto("支付时间",
					DateUtil.formatDate(notifyBizDto.getPayTime(), "yyyy年MM月dd日 HH:mm:ss"), 1));
			messageContentCreateDtos.add(new MessageContentCreateDto("支付金额",
					"¥" + BigDecimalUtils.toString(payAmount), 2));
			messageContentCreateDtos.add(new MessageContentCreateDto("支付单号", notifyBizDto.getPayNumber(), 3));
			messageContentCreateDtos.add(new MessageContentCreateDto("支付项目", product, 4));

			messageCenterCreateBizDto.setMessageCenterCreateDto(messageCenterCreateDto);
			messageCenterCreateBizDto.setMessageContentCreateDtoList(messageContentCreateDtos);
			messageCenterBizService.careteMessageCenterBiz(messageCenterCreateBizDto);

			if (isAudit) {
				// 发送审核信息给客服
				pushMsgToService(notifyBizDto, userDto, tmp);
			}
			
		} catch (Exception e) {
			String msg = "订购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成发送消息信息异常：";
			logger.error(msg, e);
		}
	}

	private void pushMsgToService(NotifyBizDto notifyBizDto, UserDto userDto, String tmp) {
		try {
			List<RiskEmailDto> riskEmailDtos = riskEmailService.getByType(RiskEmailTypeEnum.ORDER_ONE.getValue(),
					null);
			if (riskEmailDtos == null || riskEmailDtos.isEmpty()) {
				return;
			}
			JSONObject json = new JSONObject();
			// 用户姓名
			json.put("name", userDto.getRealName());
			// 手机号
			json.put("phone", userDto.getPhone());
			// 订单号
			json.put("order", notifyBizDto.getOrderCode());
			List<String> emailRecipients = new ArrayList<>();
			List<String> emailCopys = new ArrayList<>();
			String dingTalkUrl = null;
			for (RiskEmailDto riskEmailDto : riskEmailDtos) {
				if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.PHONE_SMS.getValue()) {
					try {
						Thread.sleep(100);
						// 发送短信
						smsBizService.sendMessage(riskEmailDto.getEmail(), SmsTemplateEnum.ORDER_AUDIT_SMS.getValue(),
								json.toJSONString(), null);
					} catch (Exception e) {
						logger.error("审核提醒({}:{})短信发送失败", riskEmailDto.getName(), riskEmailDto.getEmail());
					}
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.EMAIL_RECIPIENT.getValue()) {
					emailRecipients.add(riskEmailDto.getEmail());
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.EMAIL_COPY.getValue()) {
					emailCopys.add(riskEmailDto.getEmail());
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.DINGTALK_WEBHOOK.getValue()) {
					dingTalkUrl = riskEmailDto.getEmail();
				}
			}

			if (emailRecipients.isEmpty()) {
				return;
			}
			// 发送邮件
			String subject = "订单审核通知--" + notifyBizDto.getOrderCode();
			String content = "亲，有新的订阅里程服务订单需要审核，请尽快登录“OP后台》订单【"+tmp+"】”进行处理。<br />"
					+"订单编号：" + notifyBizDto.getOrderCode() + "<br />"
					+"用户姓名：" + userDto.getRealName() + "<br />"
					+"联系方式：" + userDto.getPhone() + "<br /><br />"
					+"此邮件为系统自动发送，请勿回复。";
			EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD, subject, content, emailRecipients,
					(emailCopys.isEmpty() ? null : emailCopys));
			content = "亲，有新的【" + tmp + "】订单需要审核，用户姓名：" + userDto.getRealName() + "(" + userDto.getPhone()
					+ ")，订单号：" + notifyBizDto.getOrderCode() + "，请尽快联系用户完成回访及订单审核。";
			// 发送钉钉
			DingTalkUtil.execute(dingTalkUrl, content);

		} catch (Exception e) {
			String msg = "订购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成发送审核信息给客服异常：";
			logger.error(msg, e);
		}
	}

	/**
	 * 去除延时任务
	 * 
	 * @param orderCode
	 */
	private void deleteDelay(Long orderCode) {
		try {
			orderDelayBizService.delete(orderCode);
		} catch (Exception e) {
			logger.error("支付完成，删除延时任务异常：", e);
		}
	}

	/**
	 * 结算支付发票
	 * 
	 * @param notifyBizDto
	 */
	private void createSettlementInvoice(NotifyBizDto notifyBizDto) {
		try {
			List<InvoiceCreateDto> invoiceCreateDtos = null;
			// 结算
			OrderSubscribeSettlementDto orderSubscribeSettlement = orderSubscribeSettlementService
					.getOrderSubscribeSettlement(notifyBizDto.getOrderCode());
			// 查询订单信息
			OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(notifyBizDto.getOrderCode());
			// 查询门店信息
			StoreDto storeDto = storeService.getStoreById(orderSubscribe.getPlaceStoreId());
			// 查询经销商信息
			DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
			invoiceCreateDtos = new ArrayList<>();
			if (orderSubscribeSettlement.getDamageFee() != null
					&& orderSubscribeSettlement.getDamageFee().compareTo(BigDecimal.ZERO) > 0) {
				// 结算质损费用
				invoiceCreateDtos.add(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto,
						orderSubscribeSettlement.getDamageFee(), InvoiceTypeEnum.QUALITY_LOSS));
			}
			if (orderSubscribeSettlement.getBeyondMileageFee() != null
					&& orderSubscribeSettlement.getBeyondMileageFee().compareTo(BigDecimal.ZERO) > 0) {
				// 结算超里程费用
				invoiceCreateDtos.add(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto,
						orderSubscribeSettlement.getBeyondMileageFee(), InvoiceTypeEnum.BEYOND_MILEAGE));
			}
			if (orderSubscribeSettlement.getBeyondDayFee() != null
					&& orderSubscribeSettlement.getBeyondDayFee().compareTo(BigDecimal.ZERO) > 0) {
				// 结算超期费用
				invoiceCreateDtos.add(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto,
						orderSubscribeSettlement.getBeyondDayFee(), InvoiceTypeEnum.TIME_OUT));
			}
			// 生成发票信息
			createInvoice(invoiceCreateDtos, notifyBizDto.getPayNumber());
		} catch (Exception e) {
			String msg = "结算(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成创建发票信息异常：";
			logger.error(msg, e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + msg + e.getMessage());
		}
	}

	/**
	 * 加购支付发票
	 * 
	 * @param notifyBizDto
	 */
	private void createPurchaseInvoice(NotifyBizDto notifyBizDto) {
		try {
			List<InvoiceCreateDto> invoiceCreateDtos = null;
			OrderMileageDto orderMileage = orderMileageService.getOrderMileage(notifyBizDto.getOrderCode());
			// 查询主订单信息
			OrderSubscribeDto orderSubscribe = orderSubscribeService
					.getOrderSubscribe(orderMileage.getMasterOrderCode());
			// 查询门店信息
			StoreDto storeDto = storeService.getStoreById(orderSubscribe.getPlaceStoreId());
			// 查询经销商信息
			DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
			invoiceCreateDtos = new ArrayList<>();
			invoiceCreateDtos.add(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto,
					orderMileage.getPurchaseFee(), InvoiceTypeEnum.ADD_MILEAGE));
			if (orderMileage.getBeyondFee() != null && orderMileage.getBeyondFee().compareTo(BigDecimal.ZERO) > 0) {
				// 存在超里程
				invoiceCreateDtos.add(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto,
						orderMileage.getBeyondFee(), InvoiceTypeEnum.BEYOND_MILEAGE));
			}
			// 生成发票信息
			createInvoice(invoiceCreateDtos, notifyBizDto.getPayNumber());
		} catch (Exception e) {
			String msg = "加购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成创建发票信息异常：";
			logger.error(msg, e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + msg + e.getMessage());
		}
	}

	/**
	 * 续订支付发票
	 * 
	 * @param notifyBizDto
	 */
	private void createRenewInvoice(NotifyBizDto notifyBizDto) {
		try {
			List<InvoiceCreateDto> invoiceCreateDtos = null;
			OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(notifyBizDto.getOrderCode());
			// 查询门店信息
			StoreDto storeDto = storeService.getStoreById(orderSubscribe.getPlaceStoreId());
			// 查询经销商信息
			DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
			invoiceCreateDtos = Arrays
					.asList(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto));
			// 生成发票信息
			createInvoice(invoiceCreateDtos, notifyBizDto.getPayNumber());
		} catch (Exception e) {
			String msg = "续订(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成创建发票信息异常：";
			logger.error(msg, e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + msg + e.getMessage());
		}
	}

	/**
	 * 还款支付发票
	 * 
	 * @param notifyBizDto
	 */
	private void createRepaymentInvoice(NotifyBizDto notifyBizDto) {
		try {
			List<InvoiceCreateDto> invoiceCreateDtos = null;
			OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(notifyBizDto.getOrderCode());
			// 查询排期信息
			OrderScheduleDto orderScheduleDto = orderScheduleService.getOrderSchedule(notifyBizDto.getScheduleId());
			// 查询门店信息
			StoreDto storeDto = storeService.getStoreById(orderExclusivel.getPlaceStoreId());
			// 查询经销商信息
			DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
			// 转换数据
			invoiceCreateDtos = Arrays.asList(
					Convert.toInvoiceCreateDto(notifyBizDto, orderExclusivel, orderScheduleDto, dealerDetailDto));
			// 生成发票信息
			createInvoice(invoiceCreateDtos, notifyBizDto.getPayNumber());
		} catch (Exception e) {
			String msg = "还款(" + notifyBizDto.getOrderCode() + ":" + notifyBizDto.getScheduleId() + ")支付(支付流水号："
					+ notifyBizDto.getPayNumber() + ")完成创建发票信息异常：";
			logger.error(msg, e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + msg + e.getMessage());
		}

	}

	/**
	 * 订购支付发票
	 * 
	 * @param notifyBizDto
	 */
	private void createSubscribeInvoice(NotifyBizDto notifyBizDto) {
		try {
			List<InvoiceCreateDto> invoiceCreateDtos = null;
			// 判断业务类型
			if (PaymentBusinessTypeEnum.EXCLUSIVEL.equals(notifyBizDto.getBusinessType())) {
				// 专属订单
				OrderExclusivelDto orderExclusivel = orderExclusivelService
						.getOrderExclusivel(notifyBizDto.getOrderCode());
				// 查询门店信息
				StoreDto storeDto = storeService.getStoreById(orderExclusivel.getPlaceStoreId());
				// 查询经销商信息
				DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
				if (OrderPaymentMethodEnum.INSTALLMENT.equals(orderExclusivel.getPaymentMethod())) {
					// 分期订单，查询首期信息
					OrderScheduleDto orderScheduleDto = orderScheduleService
							.getOrderScheduleByPeriods(notifyBizDto.getOrderCode(), 1);
					invoiceCreateDtos = Arrays
							.asList(Convert.toInvoiceCreateDto(notifyBizDto, orderExclusivel, orderScheduleDto,
									dealerDetailDto));
				} else if (OrderPaymentMethodEnum.FULL.equals(orderExclusivel.getPaymentMethod())) {
					// 全款订单，查询排期信息
					List<OrderScheduleDto> orderScheduleDtos = orderScheduleService
							.getOrderSchedule(notifyBizDto.getOrderCode());
					invoiceCreateDtos = Convert.toInvoiceCreateDto(notifyBizDto, orderScheduleDtos, orderExclusivel,
							dealerDetailDto);
				}

			} else if (PaymentBusinessTypeEnum.SUBSCRIBE.equals(notifyBizDto.getBusinessType())) {
				// 订阅订单
				OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(notifyBizDto.getOrderCode());
				// 查询门店信息
				StoreDto storeDto = storeService.getStoreById(orderSubscribe.getPlaceStoreId());
				// 查询经销商信息
				DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
				// 转换数据
				invoiceCreateDtos = Arrays
						.asList(Convert.toInvoiceCreateDto(notifyBizDto, orderSubscribe, dealerDetailDto));
			}
			// 生成发票信息
			createInvoice(invoiceCreateDtos, notifyBizDto.getPayNumber());
		} catch (Exception e) {
			String msg = "订购(" + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成创建发票信息异常：";
			logger.error(msg, e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + msg + e.getMessage());
		}
	}

	/**
	 * 生成发票信息
	 * 
	 * @param invoiceCreateDtos
	 * @param payNumber
	 * @throws Exception
	 */
	private void createInvoice(List<InvoiceCreateDto> invoiceCreateDtos, String payNumber) throws Exception {
		// 生成发票信息
		if (!invoiceService.createInvoiceList(invoiceCreateDtos)) {
			logger.error("支付(支付流水号：" + payNumber + ")完成创建发票信息异常");
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "支付(支付流水号：" + payNumber + ")完成创建发票信息异常");
		}
	}

	/**
	 * 将用户置为已支付
	 * 
	 * @param userDto
	 */
	private void modifyUserPay(UserDto userDto) {
		try {
			userDetailService.modifyUserPayByUserId(userDto.getId());
		} catch (Exception e) {
			logger.error("支付完成将用户(" + userDto.getId() + ")置为已支付异常：", e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "支付完成将用户(" + userDto.getId() + ")置为已支付异常：" + e.getMessage());
		}
	}



	/**
	 * 续订 加购 合同生成
	 *
	 * @param notifyBizDto
	 */
	private void createContract(NotifyBizDto notifyBizDto,ContractCreateEnum contractCreateEnum) {
		// 需要发送邮件人员的邮箱信息
		List<String> emails = null;
		try {
			OrderSubscribeDto orderSubscribeDto = null;
			OrderMileageDto orderMileageDto = null;
			if(ContractCreateEnum.RENEW.equals(contractCreateEnum)){
				//续订
				orderSubscribeDto = orderSubscribeService.getOrderSubscribe(notifyBizDto.getOrderCode());

			}else if(ContractCreateEnum.PURCHASE.equals(contractCreateEnum)){
				//加购
				orderMileageDto = orderMileageService.getOrderMileage(notifyBizDto.getOrderCode());
				if(null == orderMileageDto){
					throw new BizException("加购订单信息为空");
				}
				//查询主订单
				orderSubscribeDto = orderSubscribeService.getOrderSubscribe(orderMileageDto.getMasterOrderCode());
			}
			if(null == orderSubscribeDto){
				throw new BizException("订单信息为空");
			}

			//通过下单门店id查询经销商id
			StoreDto storeDto = storeService.getStoreById(orderSubscribeDto.getPlaceStoreId());
			if(null == storeDto || null == storeDto.getDealerId()){
				throw new BizException("门店信息为空");
			}
			//通过经销商id查询经销商信息
			DealerDto dealerDto = dealerService.getDealerById(storeDto.getDealerId());
			if(null == dealerDto || null == dealerDto.getFullName()){
				throw new BizException("经销商信息为空");
			}
			//通过经销商id查询分子公司id
			DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(storeDto.getDealerId());
			if(null == dealerDetailDto || null == dealerDetailDto.getSubcompanyId()){
				throw new BizException("经销商详细信息为空");
			}
			//通过分子公司id查询分子公司信息
			SubcompanyDto subcompanyDto = subcompanyService.getSubcompanyNameById(dealerDetailDto.getSubcompanyId());
			if(null == subcompanyDto){
				throw new BizException("分子公司信息为空");
			}
			//根据用户id查询用户信息
			UserBizDto userBizDto = userBizService.getUser(orderSubscribeDto.getUserId());
			if(null == userBizDto){
				throw new BizException("用户信息为空");
			}
			//区id查询省市区
			RegionInfoDto regionInfoDto = regionService.getCityNameByAreaId(userBizDto.getRegionId());
			if(null == regionInfoDto){
				throw new BizException("省市区信息为空");
			}

			//获取车辆信息
			CarDetailBizDto carDetailBizDto = carBizService.getCarDetail(orderSubscribeDto.getCarId());
			if (null == carDetailBizDto) {
				throw new Exception("车辆信息为空");
			}

			// 查询车型信息
			VehicleNameBizDto vehicleBizDto = vehicleBizService.getCarByModel(carDetailBizDto.getVehicleId());
			if (null == vehicleBizDto) {
				throw new Exception("车型信息为空");
			}

			//获取车身颜色
			VehicleColorDto vehicleColorDto = vehicleColorService.getVehicleColorByvehicleColorId(carDetailBizDto.getVehicleColorId());
			if (null == vehicleColorDto) {
				throw new Exception("车身颜色为空");
			}

			// 查询文件存储配置
			UploadFileRequestDto uploadFileRequestDto = fileStorageBffService.getFileStorageConfig("contract");
			if (uploadFileRequestDto == null) {
				throw new Exception("文件存储配置查询失败");
			}

			ContractMileagePurchasedBizCreateDto contractMileagePurchasedBizCreateDto = new ContractMileagePurchasedBizCreateDto();

			//业务类型(1:订阅里程,2:专属里程,3:经销商)
			contractMileagePurchasedBizCreateDto.setBusinessType(ContractBusinessTypeEnum.SUBSCRIBE.getValue());
			//丙方(经销商)
			contractMileagePurchasedBizCreateDto.setPartyCName(dealerDto.getFullName());
			//丙方id(经销商)
			contractMileagePurchasedBizCreateDto.setPartyCId(dealerDto.getDealerId().longValue());
			//丙方联系地址(经销商)
			contractMileagePurchasedBizCreateDto.setPartyCAddress(dealerDetailDto.getAddress());
			//乙方
			contractMileagePurchasedBizCreateDto.setPartyBName(userBizDto.getRealName());
			//乙方id
			contractMileagePurchasedBizCreateDto.setPartyBId(userBizDto.getId().longValue());
			//乙方身份证号
			contractMileagePurchasedBizCreateDto.setPartyBCard(userBizDto.getIdNumber());
			//乙方通信地址
			contractMileagePurchasedBizCreateDto.setPartyBAddress(regionInfoDto.getProvinceFullName()+regionInfoDto.getCityFullName()+regionInfoDto.getAreaFullName()+userBizDto.getAddress());
			//乙方电话
			contractMileagePurchasedBizCreateDto.setPartyBPhone(userBizDto.getPhone());
			//甲方1名称(资产公司)
			contractMileagePurchasedBizCreateDto.setPartyAOName(subcompanyDto.getFullName());
			//甲方1id(资产公司)
			contractMileagePurchasedBizCreateDto.setPartyAOId(subcompanyDto.getId().longValue());
			//甲方1联系地址(资产公司)
			contractMileagePurchasedBizCreateDto.setPartyAOAddress(subcompanyDto.getAddress());
			//签订日期
			contractMileagePurchasedBizCreateDto.setSigningDate(DateUtil.formatDate(LocalDate.now()));
			//车辆型号
			contractMileagePurchasedBizCreateDto.setModelName(vehicleBizDto.getSeriesName()+" "+vehicleBizDto.getModelName());
			//车辆颜色
			contractMileagePurchasedBizCreateDto.setColorName(vehicleColorDto.getName());
			//车架号
			contractMileagePurchasedBizCreateDto.setVin(carDetailBizDto.getVin());
			//车牌号
			contractMileagePurchasedBizCreateDto.setLicencePlate(carDetailBizDto.getLicencePlate());
			//电机/发动机号(加购)
			contractMileagePurchasedBizCreateDto.setEngineCode(carDetailBizDto.getEngineCode());
			//订阅服务费里程值(基础里程)
			contractMileagePurchasedBizCreateDto.setSubMileageVal(orderSubscribeDto.getBaseMileage()+"公里");
			//订阅服务费里程有效时长 (单位:天)(用车时长)
			contractMileagePurchasedBizCreateDto.setSubMileageTime((orderSubscribeDto.getLeaseExpire().toEpochDay() - orderSubscribeDto.getLeaseInception().toEpochDay())+"天");
			//订阅服务费费用(单位:元)（商品租车费）
			contractMileagePurchasedBizCreateDto.setSubMileageFee(toMoney((orderSubscribeDto.getRental().add(orderSubscribeDto.getBaseMileagePrice())))+"元");
			//里程服务费里程值(单位:KM)（里程包里程数）
			contractMileagePurchasedBizCreateDto.setMilMileageVal(orderSubscribeDto.getPackageMileage()+"公里");
			//里程服务费里程有效时长 (单位:天)(用车时长)
			contractMileagePurchasedBizCreateDto.setMilMileageTime((orderSubscribeDto.getLeaseExpire().toEpochDay() - orderSubscribeDto.getLeaseInception().toEpochDay())+"天");
			//里程服务费费用(单位:元)（里程包价格）
			contractMileagePurchasedBizCreateDto.setMilMileageFee(toMoney(orderSubscribeDto.getPackageMileagePrice())+"元");
			//赠送里程里程值(单位:KM)（赠送里程）
			contractMileagePurchasedBizCreateDto.setGiveMileageVal(orderSubscribeDto.getGiftMileage()+"公里");
			//赠送里程里程有效时长 (单位天)(用车时长)
			contractMileagePurchasedBizCreateDto.setGiveMileageTime((orderSubscribeDto.getLeaseExpire().toEpochDay() - orderSubscribeDto.getLeaseInception().toEpochDay())+"天");

			if(ContractCreateEnum.RENEW.equals(contractCreateEnum)){

				//续订
				//订单code
				contractMileagePurchasedBizCreateDto.setOrderCode(notifyBizDto.getOrderCode());

				//主订单code（第一笔订单的code）
				contractMileagePurchasedBizCreateDto.setMainOrderCode(orderBizService.getMasterOrderCode(notifyBizDto.getOrderCode(),OrderTypeEnum.SUBSCRIBE));
				//订阅总里程值(单位:KM)(相加)
				contractMileagePurchasedBizCreateDto.setSubTotalMileage((orderSubscribeDto.getGiftMileage()+orderSubscribeDto.getPackageMileage()+orderSubscribeDto.getBaseMileage())+"公里");
				//订阅总费用(单位:元)(相加)
				contractMileagePurchasedBizCreateDto.setSubTotalFee(toMoney(orderSubscribeDto.getCartFee())+"元");

			}else if(ContractCreateEnum.PURCHASE.equals(contractCreateEnum)){
				//加购
				//订单code
				contractMileagePurchasedBizCreateDto.setOrderCode(orderMileageDto.getMasterOrderCode());
				Long masterOrderCode = orderBizService.getMasterOrderCode(orderMileageDto.getMasterOrderCode(),OrderTypeEnum.SUBSCRIBE);
				if(masterOrderCode.equals(orderMileageDto.getMasterOrderCode())){
					masterOrderCode = null;
				}
				//主订单code（第一笔订单的code）
				contractMileagePurchasedBizCreateDto.setMainOrderCode(masterOrderCode);
				//加购里程值 (加购 )
				contractMileagePurchasedBizCreateDto.setPurchasedMileageVal(orderMileageDto.getPurchaseMileage()+"公里");
				//加购里程费用(加购 单位:元)
				contractMileagePurchasedBizCreateDto.setPurchasedMileageFee(toMoney(orderMileageDto.getPurchaseFee())+"元");
				//订阅总里程值(单位:KM)(相加)
				contractMileagePurchasedBizCreateDto.setSubTotalMileage(orderMileageDto.getPurchaseMileage()+"公里");
				//订阅总费用(单位:元)(相加)
				contractMileagePurchasedBizCreateDto.setSubTotalFee(toMoney(orderMileageDto.getPurchaseFee())+"元");
			}
			//生效日期年（起租日）
			contractMileagePurchasedBizCreateDto.setStartYear(String.valueOf(orderSubscribeDto.getLeaseInception().getYear()));
			//生效日期月
			contractMileagePurchasedBizCreateDto.setStartMonth(String.valueOf(orderSubscribeDto.getLeaseInception().getMonthValue()));
			//生效日期日
			contractMileagePurchasedBizCreateDto.setStartDay(String.valueOf(orderSubscribeDto.getLeaseInception().getDayOfMonth()));
			//终止日期年（截止日）
			contractMileagePurchasedBizCreateDto.setEndYear(String.valueOf(orderSubscribeDto.getLeaseExpire().getYear()));
			//终止日期月
			contractMileagePurchasedBizCreateDto.setEndMonth(String.valueOf(orderSubscribeDto.getLeaseExpire().getMonthValue()));
			//终止日期日
			contractMileagePurchasedBizCreateDto.setEndDay(String.valueOf(orderSubscribeDto.getLeaseExpire().getDayOfMonth()));
			//合同签订时间
			contractMileagePurchasedBizCreateDto.setSignedTime(LocalDateTime.now());
			//合同到期日期
			contractMileagePurchasedBizCreateDto.setEndTime(orderSubscribeDto.getLeaseExpire());
			//合同生效日期
			contractMileagePurchasedBizCreateDto.setEffectiveTime(LocalDate.now());


			ContractSubscribeBizCreateDto createDto = new ContractSubscribeBizCreateDto();
			createDto.setContractCreateEnum(contractCreateEnum);
			createDto.setContractMileagePurchasedBizCreateDto(contractMileagePurchasedBizCreateDto);
			createDto.setUploadFileRequestDto(uploadFileRequestDto);
			// 添加合同
			if (!contractBizService.createSubscribeContract(createDto)) {
				logger.error("订单(" + notifyBizDto.getOrderCode() + ")生成合同失败，合同服务返回false");

				//邮件
                emails = getEmail(RiskEmailTypeEnum.CONTRACT_GENERATION_FAILED); // getRiskEmailList(RiskEmailEnum.ONE.getValue());
				if(null != emails){
					EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD, "合同生成失败", "亲，订单号"+  notifyBizDto.getOrderCode()  +"合同生成失败，请介入进一步处理。", emails);
				}else{
					logger.error("生成合同 未配置发送邮件人员的邮箱信息");
				}

				//钉钉
				DingTalkUtil.exceptionSend( "亲，订单号"+notifyBizDto.getOrderCode()+"合同生成失败，请介入进一步处理。");
			}

		} catch (Exception e) {
			String msg = (ContractCreateEnum.RENEW.equals(contractCreateEnum)? "续订(":"加购(") + notifyBizDto.getOrderCode() + ")支付(支付流水号：" + notifyBizDto.getPayNumber()
					+ ")完成创建合同信息异常：";
			logger.error(msg, e);

			//邮件
            emails = getEmail(RiskEmailTypeEnum.CONTRACT_GENERATION_FAILED); // getRiskEmailList(RiskEmailEnum.ONE.getValue());
			if(null != emails){
				EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD, "合同生成失败", "亲，订单号"+  notifyBizDto.getOrderCode()  +"合同生成失败，请介入进一步处理。", emails);
			}else{
				logger.error("生成合同 未配置发送邮件人员的邮箱信息");
			}

			//钉钉
			DingTalkUtil.exceptionSend( "亲，订单号"+notifyBizDto.getOrderCode()+"合同生成失败，请介入进一步处理。");
		}
	}

	/**
	 * 整数取整，小数保留两位小数
	 * @param b
	 * @return
	 */
	public BigDecimal toMoney(BigDecimal b) {
		if(new BigDecimal(b.intValue()).compareTo(b)==0){
			return b.setScale(0);
		}else{
			return b.setScale(2);
		}
	}


	/**
	 * 获取邮件人信息
	 * @return
	 */
	private List<String> getEmail(RiskEmailTypeEnum riskEmailTypeEnum){
		List<RiskEmailDto> riskList = riskEmailService.getByType(riskEmailTypeEnum.getValue(),RiskEmailReceiveTypeEnum.EMAIL_RECIPIENT.getValue());
		List<String> list=null;
		if(null != riskList && !riskList.isEmpty()) {
			list=new ArrayList<>();
			for (RiskEmailDto dto : riskList) {
				list.add(dto.getEmail());
			}
		}
		return list;
	}

}
